<?php

namespace App\Http\Controllers\Manage;

use App\Http\Controllers\ApiController;
use App\Http\Requests\PatientOrRecordRequest;
use App\Http\Requests\PhysicalStoreRequest;
use App\Http\Requests\PhysicalUpdateRequest;
use App\Models\MedicalPhysical;
use App\Models\MedicalRecord;
use App\Project\Filters\PhysicalFilter;
use App\Project\Transform;
use App\Transformers\MedicalPhysicalTransformer;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;

class PhysicalController extends ApiController
{
    /**
     * 体格检查
     * @param \App\Http\Requests\PhysicalStoreRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(PhysicalStoreRequest $request)
    {
        $input = (new PhysicalFilter($request))->input();

        $result = MedicalPhysical::updateOrCreate(['record_id' => $input['record_id']], $input);

        return $this->response(['id' => $result['id']]);
    }

    /**
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit(Request $request)
    {
        $data = null;
        $id   = $request->get('id');

        $cn = \Auth::user()->hospital->isCn();

        if ($cn) {
            $columns = ['*'];
        } else {
            $columns = ['id', 'record_id', 'tongue', 'examination', 'other', 'remark', 'created_at', 'updated_at'];
        }

        if ($id > 0) {

            $data = MedicalPhysical::findOrFail($id, $columns);
        } elseif ($record_id = $request->get('record_id')) {

            $data = MedicalPhysical::where(['record_id' => $record_id])->first($columns);
        } else {
            abort(400, '缺失体格检查ID，或者病历ID');
        }

        if (empty($data)) {
            throw (new ModelNotFoundException())->setModel(MedicalPhysical::class);
        }

        return $this->item($data, new MedicalPhysicalTransformer());
    }

    /**
     * @param \App\Http\Requests\PhysicalUpdateRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(PhysicalUpdateRequest $request)
    {
        $where = [];

        if ($id = $request->input('id')) {
            $where['id'] = $id;
        } else {
            $where['record_id'] = $request->input('record_id');
        }

        $input = (new PhysicalFilter($request))->except(['id', 'record_id']);

        $input = (new Transform())->setArray($input)
                                  ->convertArrayToJson(['tongue', 'examination', 'cn_examination', 'other'])
                                  ->get();

        $result = MedicalPhysical::where($where)->update($input);

        return $this->responseForUpdate($result);
    }

    /**
     * 获取上一次体格检查
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function previous(PatientOrRecordRequest $request)
    {
        $input = $request->only('patient_id', 'record_id');

        if ($input['record_id']) {

            return $this->previousWithRecordId($input['record_id']);
        }

        return $this->previousWithPatientId($input['patient_id']);
    }

    /**
     * @param $record_id
     * @return \Illuminate\Http\JsonResponse
     */
    protected function previousWithRecordId($record_id)
    {
        $record = new MedicalRecord();

        try {
            $previous = $record->previous($record_id);
        } catch (\InvalidArgumentException $exception) {
            return $this->setMessage($exception->getMessage())
                        ->setCode(40400)
                        ->hasNoData();
        }

        $physical = MedicalPhysical::where('record_id', $previous->id)->first();

        return $this->item($physical, new MedicalPhysicalTransformer());
    }

    /**
     * @param $patient
     * @return \Illuminate\Http\JsonResponse
     */
    protected function previousWithPatientId($patient)
    {
        $record_id = MedicalRecord::previousWithPatient($patient)->first(['id']);

        $physical = MedicalPhysical::where('record_id', $record_id->id)->first();

        return $this->item($physical, new MedicalPhysicalTransformer());
    }
}
